package com.yanqu.road.server.cmd.giftKey.task;

import com.yanqu.road.entity.enums.eChannelType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.giftKey.GiftKeyInfo;
import com.yanqu.road.logic.bussiness.giftKey.GiftKeyBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.giftKey.GiftKeyProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.cmd.base.BaseTask;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.giftKey.GiftKeyModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.*;
import java.util.List;
import java.util.Objects;

public class ExchangeGiftKeyTask extends BaseTask {

    private String key;

    private String reward;

    private int playType;

    private GiftKeyInfo giftKeyInfo;

    public ExchangeGiftKeyTask(YanQuMessage packet, GamePlayer player) {
        super(packet, player);
    }

    @Override
    protected boolean parseData() throws Exception {
        GiftKeyProto.ExchangeGiftKeyReqMsg reqMsg = GiftKeyProto.ExchangeGiftKeyReqMsg.parseFrom(packet.getBytes());
        key = reqMsg.getKey();
        key = key.replaceAll(" ", "");
        return true;
    }

    @Override
    protected void execute() {
        GiftKeyModule giftKeyModule = player.getModule(GiftKeyModule.class);
        if (giftKeyModule.isUseKey(key)) {
            ret = GameErrorCode.E_GIFT_KEY_USED;
            return;
        }
        if (key.startsWith("jwdzg") && key.length() >= 13) {
            Connection conn = null;
            try {
                List<String> stringList = StringUtils.stringToStringList(ChannelConfig.CHANNEL_CENTER_DB_PARAM, "\\|");
                if (stringList.size() != 5) {
                    logger.error("player {}  use dzg code error. key is : {} ,db connect param error:{}", player.getUserId(), key, ChannelConfig.CHANNEL_CENTER_DB_PARAM);
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }

                String ip = stringList.get(0);
                String port = stringList.get(1);
                String dbName = stringList.get(2);

                String username = stringList.get(3);
                String password = stringList.get(4);

                String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName + "?useUnicode=true&characterEncoding=utf8&useSSL=false";
                conn = DriverManager.getConnection(url, username, password);
                String sql = "select * from t_s_exchange_code_list where exchangeCode = ?";
                PreparedStatement ps = conn.prepareStatement(sql);
                ps.setString(1, key);
                ResultSet rs = ps.executeQuery();
                giftKeyInfo = new GiftKeyInfo();
                while (rs.next()) {
                    String exchangeCode = rs.getString("exchangeCode");
                    int state = rs.getInt("state");
                    int configId = rs.getInt("configId");
                    giftKeyInfo.setExchangeCode(exchangeCode);
                    giftKeyInfo.setConfigId(configId);
                    giftKeyInfo.setUseTimes(state);
                    break;
                }
                rs.close();
                ps.close();
                if (giftKeyInfo == null) {
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }
                sql = "select * from t_s_exchange_code_conf where id = ?";
                ps = conn.prepareStatement(sql);
                ps.setInt(1, giftKeyInfo.getConfigId());
                rs = ps.executeQuery();
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String reward = rs.getString("awards");
                    boolean isEnable = rs.getBoolean("isEnable");
                    int playType = rs.getInt("playType");
                    int codeType = rs.getInt("codeType");
                    int maxLimit = rs.getInt("maxLimit");

                    giftKeyInfo.setReward(reward);
                    giftKeyInfo.setEnable(isEnable);
                    giftKeyInfo.setPlayType(playType);
                    giftKeyInfo.setCodeType(codeType);
                    giftKeyInfo.setMaxLimit(maxLimit);
                    giftKeyInfo.setStartTime(rs.getDate("startTime").getTime() / 1000);
                    giftKeyInfo.setEndTime(rs.getDate("endTime").getTime() / 1000);
                    giftKeyInfo.setChannelIdList(StringUtils.stringToIntegerList(rs.getString("channelId"), ","));
                    giftKeyInfo.setServerIdList(StringUtils.stringToLongList(rs.getString("serverId"), ","));
                    giftKeyInfo.setReceiveNum(rs.getInt("receiveNum"));
                    break;
                }
                rs.close();
                ps.close();
                if (!giftKeyInfo.isEnable()) {
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }
                if (giftKeyInfo.getCodeType() == 2) {
                    if (giftKeyInfo.getUseTimes() > 0) {
                        ret = GameErrorCode.E_GIFT_KEY_USED;
                        return;
                    }
                } else if (giftKeyInfo.getCodeType() == 1) {//通用码 限制非0要限制次数
                    if (giftKeyInfo.getMaxLimit() > 0 && giftKeyInfo.getUseTimes() >= giftKeyInfo.getMaxLimit()) {
                        ret = GameErrorCode.E_GIFT_KEY_COMMON_LIMIT;
                        return;
                    }
                } else {
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }

                long nowTime = System.currentTimeMillis() / 1000;
                if (nowTime < giftKeyInfo.getStartTime() || nowTime > giftKeyInfo.getEndTime()) {
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }
                if (!StringUtils.isNullOrEmpty(giftKeyInfo.getAppId())) {
                    List<String> appIdList = StringUtils.stringToStringList(giftKeyInfo.getAppId(), ",");
                    // 如果兑换码的appId不为空 则要比对appId
                    if (!appIdList.contains(player.getUserInfo().getAppId())) {
                        // 如果用户appId与兑换码appId不一致 则无法兑换
                        ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
                        return;
                    }
                }

                int channelId = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId()).getChannelId();
                if (!giftKeyInfo.isChannelIdIn(channelId)) {
                    ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
                    return;
                }
                long serverId = GameServer.getInstance().getServerId();
                if (!giftKeyInfo.isServerIdIn(serverId)) {
                    ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
                    return;
                }

                if (giftKeyInfo.getCodeType() == 1 || giftKeyInfo.getCodeType() == 2) {//一码一用
                    String useNumsql = "select count(*) as num from t_s_exchange_code_use where userId=? and exchangeCode = ?";
                    try {
                        ps = conn.prepareStatement(useNumsql);
                        int i = 1;
                        ps.setLong(1, player.getUserId());
                        ps.setString(2, giftKeyInfo.getExchangeCode());
                        rs = ps.executeQuery();
                        if (rs.next()) {
                            int num = rs.getInt("num");
                            if (num > 0) {
                                ret = GameErrorCode.E_GIFT_KEY_USED;
                                return;
                            }
                        }
                    } catch (Exception e) {
                        logger.error("player {}  use dzg code error. key is : {} ", player.getUserId(), key, e);
                        ret = GameErrorCode.E_GIFT_KEY_ERR;
                        return;
                    } finally {
                        rs.close();
                        ps.close();
                    }
                }

                if (giftKeyInfo.getCodeType() == 2) {//判断同配置的有没有超过使用次数
                    String useNumsql = "select count(*) as num from t_s_exchange_code_use where userId=? and configId = ? and useTime>0 ";
                    try {
                        ps = conn.prepareStatement(useNumsql);
                        int i = 1;
                        ps.setLong(1, player.getUserId());
                        ps.setInt(2, giftKeyInfo.getConfigId());
                        rs = ps.executeQuery();
                        if (rs.next()) {
                            int num = rs.getInt("num");
                            if (num >= giftKeyInfo.getReceiveNum()) {
                                ret = GameErrorCode.E_GIFT_KEY_ONCE_LIMIT;
                                return;
                            }
                        }
                    } catch (Exception e) {
                        logger.error("player {}  use dzg code error. key is : {} ", player.getUserId(), key, e);
                        ret = GameErrorCode.E_GIFT_KEY_ERR;
                        return;
                    } finally {
                        rs.close();
                        ps.close();
                    }
                }

                int rowUpdate = 0;
                //1是通用码2是用一次的激活码
                String updateSql = "update t_s_exchange_code_list set state = state + 1 where exchangeCode = ?";
                ps = conn.prepareStatement(updateSql);
                ps.setString(1, key);
                rowUpdate = ps.executeUpdate();
                ps.close();
                if (rowUpdate > 0) {
                    player.getModule(GiftKeyModule.class).addGiftKeyUse(giftKeyInfo);
                    player.getModule(CurrencyModule.class).addCurrency(giftKeyInfo.getReward(), eLogMoneyType.Activity, eLogMoneyType.ExchangeReward);
                    reward = giftKeyInfo.getReward();
                    playType = giftKeyInfo.getPlayType();

                    String insertSql = "INSERT INTO t_s_exchange_code_use(configId,userId,exchangeCode,useTime) VALUES(?,?,?,?)";
                    try {
                        ps = conn.prepareStatement(insertSql);
                        ps.setInt(1, giftKeyInfo.getConfigId());
                        int i = 1;
                        ps.setInt(i++, giftKeyInfo.getConfigId());
                        ps.setLong(i++, player.getUserId());
                        ps.setString(i++, giftKeyInfo.getExchangeCode());
                        ps.setLong(i++, nowTime);
                        ps.executeUpdate();
                    } catch (Exception e) {
                        logger.error("player {}  use dzg code error. key is : {} ", player.getUserId(), key, e);
                    } finally {
                        ps.close();
                    }

                } else {
                    ret = GameErrorCode.E_GIFT_KEY_ERR;
                    return;
                }

            } catch (Exception e) {
                logger.error("player {}  use dzg code error. key is : {} ", player.getUserId(), key, e);
                ret = GameErrorCode.E_GIFT_KEY_ERR;
                return;
            } finally {
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        logger.error("player {}  use dzg code error. key is : {} ", player.getUserId(), key, e);
                    }
                }
            }
            return;
        }


        giftKeyInfo = GiftKeyBussiness.getGiftKeyInfo(key);
        if (null == giftKeyInfo || !Objects.equals(key, giftKeyInfo.getExchangeCode())) {
            ret = GameErrorCode.E_GIFT_KEY_ERR;
            return;
        }
        if (giftKeyModule.isUseKey(giftKeyInfo.getExchangeCode())) {
            ret = GameErrorCode.E_GIFT_KEY_USED;
            return;
        }
        if (player.getModule(GiftKeyModule.class).isOnceUseLimitKey(giftKeyInfo)) {
            ret = GameErrorCode.E_GIFT_KEY_ONCE_LIMIT;
            return;
        }
        if (player.getModule(GiftKeyModule.class).isCommonUseLimitKey(giftKeyInfo)) {
            ret = GameErrorCode.E_GIFT_KEY_COMMON_LIMIT;
            return;
        }
        if (!giftKeyInfo.isEnable()) {
            ret = GameErrorCode.E_GIFT_KEY_ERR;
            return;
        }
        //无用
        if (giftKeyInfo.getCodeType() != 1 && giftKeyInfo.getUseTimes() > 0) {
            ret = GameErrorCode.E_GIFT_KEY_USED;
            return;
        }

        if (!StringUtils.isNullOrEmpty(giftKeyInfo.getAppId())) {
            List<String> appIdList = StringUtils.stringToStringList(giftKeyInfo.getAppId(), ",");
            // 如果兑换码的appId不为空 则要比对appId
            if (!appIdList.contains(player.getUserInfo().getAppId())) {
                // 如果用户appId与兑换码appId不一致 则无法兑换
                ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
                return;
            }
        }

        int channelId = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId()).getChannelId();
        if (!giftKeyInfo.isChannelIdIn(channelId)) {
            ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
            return;
        }
        long serverId = GameServer.getInstance().getServerId();
        if (!giftKeyInfo.isServerIdIn(serverId)) {
            ret = GameErrorCode.E_GIFT_KEY_TARGET_ERR;
            return;
        }
        long nowTime = System.currentTimeMillis() / 1000;
        if (nowTime < giftKeyInfo.getStartTime() || nowTime > giftKeyInfo.getEndTime()) {
            ret = GameErrorCode.E_GIFT_KEY_ERR;
            return;
        }

        int rowUpdate = 0;
        //1是通用码2是用一次的激活码
        if (giftKeyInfo.getCodeType() == 1) {
            rowUpdate = GiftKeyBussiness.updateNormalGiftKeyUseTimes(key);
        } else if (giftKeyInfo.getCodeType() == 2) {
            rowUpdate = GiftKeyBussiness.updateOnceGiftKeyUseTimes(key);
        }

        if (rowUpdate > 0) {
            player.getModule(GiftKeyModule.class).addGiftKeyUse(giftKeyInfo);
            player.getModule(CurrencyModule.class).addCurrency(giftKeyInfo.getReward(), eLogMoneyType.Activity, eLogMoneyType.ExchangeReward);
            reward = giftKeyInfo.getReward();
            playType = giftKeyInfo.getPlayType();
        } else {
            ret = GameErrorCode.E_GIFT_KEY_ERR;
            return;
        }
    }

    @Override
    protected void sendData(GamePlayer player) {
        GiftKeyProto.ExchangeGiftKeyRespMsg.Builder respMsg = GiftKeyProto.ExchangeGiftKeyRespMsg.newBuilder();
        respMsg.setRet(ret);
        if (ret == 0) {
            respMsg.setReward(reward);
            respMsg.setPlayType(playType);

            if (playType == 2) {
                respMsg.setKey(key);
                GiftKeyProto.SlideRedPacketSettingMsg.Builder slideRedPacketMsg = GiftKeyProto.SlideRedPacketSettingMsg.newBuilder();
                slideRedPacketMsg.setStartTime(player.getModule(GiftKeyModule.class).getUserGiftKeyRedPacketMap().get(key).getStartTime());
                slideRedPacketMsg.setSettings(giftKeyInfo.getSlideSettings());
                respMsg.setRedPacket(slideRedPacketMsg);
            }
        }
        player.sendPacket(Protocol.U_USE_GIFT_KEY, respMsg);
    }

}
